// module name: ImmGen
// description:
//          to generate 32 immediate number from different type of instructions
// author: yangtao2019
// date: 2021.07.10

`timescale 1ns / 1ps

module ImmGne(
    input[31:0] inst,
    output[63:0] immNumEXT
);
    wire [6:0] opcode;
    wire [11:0] ISB_immNum, ISB_immNumEXT;
    wire [19:0] UJ_immNum;

    // noted R-type require no immediate number
    assign ISB_immNum = (opcode==7'b000_0011)?inst[31:20]:                                 // I-type(load, etc.) problem!! -> U auipc(31:12?)
                        (opcode==7'b001_0011)?inst[31:20]:                                 // I-type(addi, etc.)
                        (opcode==7'b010_0011)?{inst[31:25],inst[11:7]}:                    // S-type
                        (opcode==7'b110_0011)?{inst[31],inst[7],inst[30:25],inst[11:8]}:   // B-type
                        (opcode==7'b110_0111)?inst[31:20]:                                 // J-type(jalr)
                        12'b0;                                                             // default situation
                
                
    assign UJ_immNum =  (opcode==7'b001_0111)?inst[31:12]:                                 // U-type(auipc)
                        (opcode==7'b011_0111)?inst[31:12]:                                 // U-type(lui)
                        (opcode==7'b110_1111)?{inst[31],inst[19:12],inst[20],inst[30:21]}: // J-type(jal)
                        20'b0;                                                             // default situation


    // assume no overlap occurs
    signEXT0#(.WIDTH_in(12), .WIDTH_out(20)) signext20(.in(ISB_immNum), .out(ISB_immNumEXT));
    signEXT1#(.WIDTH_in(20), .WIDTH_out(64)) signnext32(.in(ISB_immNumEXT|UJ_immNum), .out(immNumEXT));

endmodule
